package in.equilibr.ingredients.dao;

import in.equilibr.ingredients.model.Activity;

import java.util.ArrayList;
import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

import org.apache.lucene.search.Query;
import org.hibernate.search.jpa.FullTextEntityManager;
import org.hibernate.search.jpa.FullTextQuery;
import org.hibernate.search.jpa.Search;
import org.hibernate.search.query.dsl.QueryBuilder;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

@Repository
public class ActivityDAO {
	@PersistenceContext
	private EntityManager entityManager;

	@SuppressWarnings("unchecked")
	public List<Activity> getActivities(int limit) {
		javax.persistence.Query query = entityManager
				.createQuery("from Activity order by Name");
		query.setMaxResults(limit);
		return query.getResultList();
	}

	@SuppressWarnings("unchecked")
	public List<Activity> getActivitiesByParentId(Integer parentId) {
		String condition;
		if (parentId == null)
			condition = "ParentID is null";
		else
			condition = "ParentID=" + parentId;
		javax.persistence.Query query = entityManager
				.createQuery("from Activity where " + condition
						+ " order by Name");
		return query.getResultList();
	}

	@Transactional
	public void addActivity(Activity activity) {
		entityManager.merge(activity);
	}

	@SuppressWarnings("unchecked")
	public Activity findActivityById(int id) {
		Activity activity = null;
		javax.persistence.Query query = entityManager
				.createQuery("from Activity where ID=" + id);
		List<Activity> list = query.getResultList();
		if (list.size() > 0)
			activity = list.get(0);
		return activity;
	}

	@Transactional
	public boolean deleteActivityById(int id) {
		Activity activity = findActivityById(id);
		if (activity != null) {
			// cascading deleting
			List<Activity> subactivities = getActivitiesByParentId(id);
			for (Activity a : subactivities)
				deleteActivityById(a.getId());
			entityManager.remove(activity);
			return true;
		}
		return false;
	}

	@SuppressWarnings("unchecked")
	public List<Activity> searchActivity(String term) {
		return entityManager.createQuery(
				"from Activity where Name like '" + term + "%'")
				.getResultList();
	}

	@SuppressWarnings("unchecked")
	public List<String> searchActivityName(String term) {
		return entityManager.createQuery(
				"select Name from Activity where Name like '" + term
						+ "%' order by Name").getResultList();
	}

	@SuppressWarnings("unchecked")
	@Transactional
	public List<String> searchSimilarActivities(String term) {
		FullTextEntityManager fullTextEntityManager = Search
				.getFullTextEntityManager(entityManager);
		QueryBuilder qb = fullTextEntityManager.getSearchFactory()
				.buildQueryBuilder().forEntity(Activity.class).get();
		Query luceneQuery = qb.keyword().fuzzy().onField("name").matching(term)
				.createQuery();

		FullTextQuery fullTextQuery = fullTextEntityManager
				.createFullTextQuery(luceneQuery, Activity.class);
		List<Activity> activities = fullTextQuery.getResultList();

		List<String> activityNames = new ArrayList<String>();

		for (Activity currentActivity : activities) {
			activityNames.add(currentActivity.getName());
		}

		fullTextEntityManager.close();
		return activityNames;
	}

	public void createSearchIndex() throws InterruptedException {
		FullTextEntityManager fullTextEntityManager = Search
				.getFullTextEntityManager(entityManager);
		fullTextEntityManager.createIndexer(Activity.class).startAndWait();
		fullTextEntityManager.close();
	}
}
